﻿using Kz.Telegram.Bot.Infrastructure.Extensions;
using Kz.Telegram.Bot.Infrastructure.Helpers;
using System.Net;
using System.Net.Http;

namespace Kz.Telegram.Bot.Infrastructure.Extensions
{
    /// <summary>
    /// 常规的HTTP请求 故障重试拓展
    /// </summary>
    public static class HttpRequestExtenisons
    {
        /// <summary>
        /// Polly 故障重试 HttpPost
        /// </summary>
        /// <typeparam name="TIn"></typeparam>
        /// <param name="_http"></param>
        /// <param name="api"></param>
        /// <param name="obj"></param>
        /// <param name="retryCount"></param>
        /// <param name="defaultReturnVal"></param>
        /// <returns></returns>
        public static async Task<(bool, string, HttpStatusCode)> PollyPostAsync<TIn>(this IHttpClientFactory _http, string api, TIn obj, int retryCount, string defaultReturnVal, string token = "")
            where TIn : class
        {
            using HttpClient _client = _http.CreateClient();

            if (!string.IsNullOrEmpty(token))
            {
                _client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
            }

            var (res, code) = await PollyHelper.RetryAndFallback<(string, HttpStatusCode), HttpRequestException>($"post", (defaultReturnVal, HttpStatusCode.Gone), retryCount, async () =>
            {
                var (res, code) = await _client.SimplePostAsync(api, obj);
                if (code == HttpStatusCode.OK)
                {
                    return (res, HttpStatusCode.OK);
                }
                else
                {
                    throw new HttpRequestException();  //抛出异常进行重试
                }
            });

            if (code == HttpStatusCode.OK)
            {
                return (true, res, HttpStatusCode.OK);
            }
            else
            {
                return (false, defaultReturnVal, code);
            }
        }

        /// <summary>
        /// Polly 故障重试 HttpGet
        /// </summary>
        /// <param name="_http"></param>
        /// <param name="api"></param>
        /// <param name="para"></param>
        /// <param name="retryCount"></param>
        /// <param name="defaultReturnVal"></param>
        /// <returns></returns>
        public static async Task<(bool, string, HttpStatusCode)> PollyGetAsync(this IHttpClientFactory _http, string api, string para, int retryCount, string defaultReturnVal)
        {
            using HttpClient _client = _http.CreateClient();

            var (res, code) = await PollyHelper.RetryAndFallback<(string, HttpStatusCode), HttpRequestException>($"get", (defaultReturnVal, HttpStatusCode.Gone), retryCount, async () =>
            {
                var (res, code) = await _client.SimpleGetAsync($"{api}{para}");
                if (code == HttpStatusCode.OK)
                {
                    return (res, HttpStatusCode.OK);
                }
                else
                {
                    throw new HttpRequestException();   //抛出异常进行重试
                }
            });

            if (code == HttpStatusCode.OK)
            {
                return (true, res, HttpStatusCode.OK);
            }
            else
            {
                return (false, defaultReturnVal, code);
            }
        }

        /// <summary>
        /// Polly 故障重试 HttpGet
        /// </summary>
        /// <param name="_http"></param>
        /// <param name="api"></param>
        /// <param name="para"></param>
        /// <param name="retryCount"></param>
        /// <param name="defaultReturnVal"></param>
        /// <returns></returns>
        public static async Task<(bool, string, HttpStatusCode)> PollyGetAsync(this IHttpClientFactory _http, string api, string para, int retryCount, string defaultReturnVal, string token = "")
        {
            using HttpClient _client = _http.CreateClient();

            if (!string.IsNullOrEmpty(token))
            {
                _client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
            }

            var (res, code) = await PollyHelper.RetryAndFallback<(string, HttpStatusCode), HttpRequestException>($"get", (defaultReturnVal, HttpStatusCode.Gone), retryCount, async () =>
            {
                var (res, code) = await _client.SimpleGetAsync($"{api}{para}");
                if (code == HttpStatusCode.OK)
                {
                    return (res, HttpStatusCode.OK);
                }
                else
                {
                    throw new HttpRequestException();   //抛出异常进行重试
                }
            });

            if (code == HttpStatusCode.OK)
            {
                return (true, res, HttpStatusCode.OK);
            }
            else
            {
                return (false, defaultReturnVal, code);
            }
        }
    }
}
